﻿using DMC.Core.Models.Dto;
using DMC.Core.Models.Queries;
using DMC.Core.Models.VO;
using DMC.Core.Providers;
using MiniFox.Components;
using MiniFox.Data;
using MiniFox.Infrastructure;
using MiniFox.Platform.Applications;
using MiniFox.Platform.Applications.Auth;
using MiniFox.Platform.Exceptions;
using MiniFox.Resources;
using System.Data;
using System.Data.Common;

namespace DMC.Core.Services.Impls
{
    [AutoResolve]
    public class CommandService : ApiServiceBase, ICommandService
    {
        public CommandService(SystemPrincipal principal) : base(principal)
        {
        }
        public object Test(CommandTestDto commandTest)
        {
            try
            {
                Database database = Database.CreateDatabase(commandTest.ConnectionString, commandTest.Provider);
                database.RaiseException = true;
                List<DbParameter> parList = new List<DbParameter>();
                foreach (var par in commandTest.Parameters)
                {
                    DbParameter p = database.CreateParameter(par.ParameterName, par.Name, par.CLRType, par.Direction);
                    p.Precision = par.Precision;
                    p.Size = par.Size;
                    p.Scale = par.Scale;

                    object val = par.DefaultValue;
                    if (val == null)
                    {
                        if (par.Nullable)
                            val = DBNull.Value;
                        else if (par.CLRType == typeof(string))
                            val = string.Empty;
                        else
                            throw new InvalidOperationException(string.Format(CommonMessages.MSG_CommonRequired, par.Name));
                    }
                    else if (val.GetType() != par.CLRType)
                    {
                        try
                        {
                            val = Convert.ChangeType(val, par.CLRType);
                        }
                        catch
                        {
                            if (par.Nullable)
                                val = DBNull.Value;
                            else
                                throw new InvalidCastException(string.Format(CommonMessages.MSG_CommonTypeUnmatched, par.Name, par.CLRType.Name));
                        }
                    }

                    p.Value = val;
                    parList.Add(p);
                }
                DataTable dataTable = new DataTable();
                var rowCount = database.FillDataTable(dataTable, commandTest.CommandText, commandTest.CommandType, commandTest.MaxRowCount, parList.ToArray());
                ResultObject<ViewTable> result = dataTable.GetDataResult((QueryObject)null);
                return result;
            }
            catch (Exception e)
            {
                Exception exception = e;
                while (exception.InnerException != null)
                {
                    exception = exception.InnerException;
                }
                throw new MiniFox.Exceptions.SystemException(exception.Message);
            }
        }

    }
}
